// GrammarIntelliForJsUIHelper.js - UI helper scripts for the GrammarIntelliForJS.js
var oGIHelperObjectTableForNonIEBrowsers = new Array(); // For non IE browser, setAttribute only takes string .hence we'll use the global table for it

function GIUIHelper(inputControl, oGIMachine) {
    this.InputControl = inputControl;
    this.GIMachine = oGIMachine;
    this.InputControlPosition = GetControlPosition(inputControl);
    this.SuggestionControl = null;
    this.Show = function() {
        this.SuggestionControl.style.display = "";
    }
    this.Hide = function() {
        this.SuggestionControl.style.display = "none";
    }
    this.Initialize = function() {
        var iGITableIndex = oGIHelperObjectTableForNonIEBrowsers.length;
        oGIHelperObjectTableForNonIEBrowsers[iGITableIndex] = this; // For non IE browser, setAttribute only takes string .hence we'll use the global table for it
        this.SuggestionControl = document.createElement('div');
        this.SuggestionControl.setAttribute("GIHelperIndex", iGITableIndex);
        this.SuggestionControl.setAttribute('id', "lyr1");       //give id to it
        this.SuggestionControl.className = "top";                 // set the style classname  
        //set the inner styling of the div tag
        this.SuggestionControl.style.position = "absolute";
        this.SuggestionControl.style.display = "none";
        //this.SuggestionControl.style.pixelLeft = 20;
        //this.SuggestionControl.style.pixelTop = 100;
        this.SuggestionControl.style.width = 110;
        this.SuggestionControl.style.height= 150;
        this.SuggestionControl.style.backgroundColor = "white";
        this.SuggestionControl.style.border = "1px solid black";
        this.SuggestionControl.style.overflow = "auto";
        //set the html content inside the div tag
        this.SuggestionControl.innerHTML = ' none ';
        this.SuggestionControl.style.left = this.InputControlPosition[0] + "px";
        this.SuggestionControl.style.top = (this.InputControlPosition[1] + this.InputControl.offsetHeight) + "px";
        document.body.appendChild(this.SuggestionControl);

        //TODO: Attach key handler for up/down/esc keys for inputControl
        // attach onkeyup to the created div tag
        this.InputControl.setAttribute("GIHelperIndex", iGITableIndex);
        if (this.InputControl.attachEvent) {        //IE
            this.InputControl.attachEvent("onkeyup", this.KeyUpHandler);
        } else
            if (this.InputControl.addEventListener) {
            this.InputControl.addEventListener("keyup", this.KeyUpHandler, false);
        } else {
            this.InputControl["onkeyup"] = this.KeyUpHandler;
        }
    }
    this.CurrentSuggestions = null;
    this.HighlightedSuggestionIndex = -1;
    this.UnHighlightSuggestion = function() {
        var oTR = null;
        if (this.HighlightedSuggestionIndex >= 0 && this.HighlightedSuggestionIndex < this.CurrentSuggestions.length) {
            oTR = this.SuggestionControl.childNodes[0].childNodes[0].childNodes[this.HighlightedSuggestionIndex];
            oTR.style.backgroundColor = "white";
        }
    }

    this.HighlightSuggestion = function(relativeJump) {
        var oTR = null;
        this.UnHighlightSuggestion();
        if (this.CurrentSuggestions != null && this.CurrentSuggestions.length > 0) {
            this.HighlightedSuggestionIndex += relativeJump;
            this.HighlightedSuggestionIndex = (this.HighlightedSuggestionIndex > this.CurrentSuggestions.length) ? 0 : (this.HighlightedSuggestionIndex < 0) ? (this.CurrentSuggestions.length - 1) : this.HighlightedSuggestionIndex;
            oTR = this.SuggestionControl.childNodes[0].childNodes[0].childNodes[this.HighlightedSuggestionIndex];
            if (oTR != null) {
                oTR.scrollIntoView(false);
                oTR.style.backgroundColor = "#cecece";
            }
        } else {
            alert("No current suggestions...");
        }
    }
    this.AppendHighlightedSuggestion = function() {
        var oSuggestion = null, lastSpacePos = -1;
        if (this.CurrentSuggestions != null && this.HighlightedSuggestionIndex >= 0 && this.HighlightedSuggestionIndex < this.CurrentSuggestions.length) {
            oSuggestion = this.CurrentSuggestions[this.HighlightedSuggestionIndex];
            if (oSuggestion.IsLiteral) {
                lastSpacePos = this.InputControl.value.lastIndexOf(" ");
                if (lastSpacePos > 0) {
                    this.InputControl.value = this.InputControl.value.substring(0, lastSpacePos + 1) + oSuggestion.Pattern;
                } else {
                    this.InputControl.value = oSuggestion.Pattern;
                }
                this.CurrentSuggestions = null;
                this.HighlightedSuggestionIndex = -1;
                this.Hide();
                this.InputControl.focus(); // if append happens due to mouse click in a suggestion then we loose focus, hence need it back
                this.InputControl.value = this.InputControl.value; // this should bring the cursor to end of text
            }
        }

    }

this.KeyUpHandler = function(e) {
    var k = (e.keyCode) ? e.keyCode : e.which, oGIHelperIndex = (e.srcElement) ? e.srcElement.getAttribute("GIHelperIndex") : e.target.getAttribute("GIHelperIndex"), oGIHelper = oGIHelperObjectTableForNonIEBrowsers[parseInt(oGIHelperIndex, 10)], sText = oGIHelper.InputControl.value, sHTML = "<table border=\"0\" cellspacing=\"2\" cellpadding=\"2\">", i = 0;
    switch (k) {
        case 27: // Esc
            oGIHelper.Hide();
            break;
        case 40: // Down Arrow
            oGIHelper.HighlightSuggestion(1);
            break;
        case 38: // Up arrow
            oGIHelper.HighlightSuggestion(-1);
            break;
        case 13: // ENTER
            oGIHelper.AppendHighlightedSuggestion();
            break;
        default:    // we process for suggestions
            oGIHelper.Show();
            oGIHelper.CurrentSuggestions = oGIHelper.GIMachine.Suggestions(sText);
            HighlightedSuggestionIndex = -1;
            if (oGIHelper.CurrentSuggestions != null && oGIHelper.CurrentSuggestions.length > 0) {
                for (i = 0; i < oGIHelper.CurrentSuggestions.length; i++) {
                    if (oGIHelper.CurrentSuggestions[i].IsLiteral) {
                        sHTML += "<tr><td nowrap=\"1\" style=\"cursor:pointer\" onClick=\"GIAppendSuggestionByMouseClick(this);\" GIHelperIndex=\"" + oGIHelperIndex + "\" SuggestionIndex=\"" + i + "\" ><b>L:</b> &nbsp;" + oGIHelper.CurrentSuggestions[i].Pattern + "</td></tr>";
                    } else {
                        sHTML += "<tr><td nowrap=\"1\"><b>R:</b> &nbsp;" + oGIHelper.CurrentSuggestions[i].Pattern + "  [" + oGIHelper.CurrentSuggestions[i].Name + "]</td></tr>";
                    }
                }
                sHTML += "</table>";
                oGIHelper.SuggestionControl.innerHTML = sHTML;
                oGIHelper.HighlightSuggestion(1);
            } else {
                oGIHelper.SuggestionControl.innerHTML = "";
            }
            break;
    } //end of switch
}
    

    return this;
} // end of GIUIHelper


function GIAppendSuggestionByMouseClick(oTD) {
    if (oTD != null) {
        var sGIHelperIndex = oTD.getAttribute("GIHelperIndex"),
        oGIHelper = oGIHelperObjectTableForNonIEBrowsers[parseInt(sGIHelperIndex, 10)],
        iSuggestionIndex = parseInt(oTD.getAttribute("SuggestionIndex"), 10);

        oGIHelper.HighlightedSuggestionIndex = iSuggestionIndex;
        oGIHelper.AppendHighlightedSuggestion();  

    } else {
        //TODO: error -- should not happen ... 
    }
        
}

function GetControlPosition(n, endNode) {
    var left = 0;
    var top = 0;
    var node = n;
    done = false;
    while (!done) {
        if (node.offsetLeft != null)
            left += node.offsetLeft;
        if (node.offsetTop != null)
            top += node.offsetTop;
        if (node.offsetParent) {
            node = node.offsetParent;
        } else {
            done = true;
        }
        if (node == endNode)
            done = true;
    }
    done = false;
    node = n;
    while (!done) {
        if (document.all && node.style && parseInt(node.style.borderLeftWidth)) {
            left += parseInt(node.style.borderLeftWidth);
        }
        if (document.all && node.style && parseInt(node.style.borderTopWidth)) {
            top += parseInt(node.style.borderTopWidth);
        }

        if (node.scrollLeft) {
            left -= node.scrollLeft;
        }
        if (node.scrollTop)
            top -= node.scrollTop;
        if (node.parentNode)
            node = node.parentNode;
        else
            done = true;
    }
    return new Array(left, top);
}
